package com.boot.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * @author bbyh
 * @since 2024-04-27
 */
public class FileUtil {
    public static final String FRAGMENT_SPLIT = "--分片";
    /**
     * 每个分片的大小：2MB
     */
    public static final Integer EACH_FRAGMENT_SIZE = 1024 * 1024 * 2;
    private static final Map<Character, String> HEX_MAP = new HashMap<>(16);
    private static final Map<Integer, Character> MD5_MAP = new HashMap<>(16);

    static {
        HEX_MAP.put('0', "0000");
        HEX_MAP.put('1', "0001");
        HEX_MAP.put('2', "0010");
        HEX_MAP.put('3', "0011");
        HEX_MAP.put('4', "0100");
        HEX_MAP.put('5', "0101");
        HEX_MAP.put('6', "0110");
        HEX_MAP.put('7', "0111");
        HEX_MAP.put('8', "1000");
        HEX_MAP.put('9', "1001");
        HEX_MAP.put('A', "1010");
        HEX_MAP.put('B', "1011");
        HEX_MAP.put('C', "1100");
        HEX_MAP.put('D', "1101");
        HEX_MAP.put('E', "1110");
        HEX_MAP.put('F', "1111");

        MD5_MAP.put(0, '0');
        MD5_MAP.put(1, '1');
        MD5_MAP.put(2, '2');
        MD5_MAP.put(3, '3');
        MD5_MAP.put(4, '4');
        MD5_MAP.put(5, '5');
        MD5_MAP.put(6, '6');
        MD5_MAP.put(7, '7');
        MD5_MAP.put(8, '8');
        MD5_MAP.put(9, '9');
        MD5_MAP.put(10, 'A');
        MD5_MAP.put(11, 'B');
        MD5_MAP.put(12, 'C');
        MD5_MAP.put(13, 'D');
        MD5_MAP.put(14, 'E');
        MD5_MAP.put(15, 'F');
    }

    public static void upload(InputStream inputStream, String fileName, String path) {
        File destinationDir = new File(path);
        if (!destinationDir.exists()) {
            destinationDir.mkdir();
        }
        File file = new File(path + fileName);
        try (FileOutputStream outputStream = new FileOutputStream(file)) {
            int available = inputStream.available();
            byte[] buf = new byte[available];
            int read = inputStream.read(buf);
            outputStream.write(buf, 0, read);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static byte[] md5ToBytes(String md5Str) {
        if (md5Str.length() != 32) {
            throw new UnsupportedOperationException("解析md5字符串出错，md5长度不是32位");
        }

        char[] charArray = md5Str.toUpperCase().toCharArray();
        StringBuilder builder = new StringBuilder();
        for (char ch : charArray) {
            if (HEX_MAP.get(ch) == null) {
                throw new UnsupportedOperationException("md5字符串内容出错");
            }
            builder.append(HEX_MAP.get(ch));
        }

        int length = 16;
        byte[] result = new byte[length];
        for (int i = 0; i < length; i++) {
            result[i] = (byte) Integer.parseInt(builder.substring(i * 8, (i + 1) * 8), 2);
        }
        return result;
    }

    public static String bytesToMd5(byte[] bytes) {
        if (bytes.length != 16) {
            throw new UnsupportedOperationException("解析md5Byte数组出错，byte长度不是16字节");
        }
        StringBuilder builder = new StringBuilder();
        for (byte aByte : bytes) {
            int high4Bits = (aByte & 0xf0) >> 4;
            int low4Bits = aByte & 0x0f;
            builder.append(MD5_MAP.get(high4Bits)).append(MD5_MAP.get(low4Bits));
        }
        return builder.toString();
    }

}
